home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / i / internet / software / tuwtcpsr / tcp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-04  |  47.3 KB  |  2,005 lines

  1. #define noVDEBUG
  2. #define nDEBUG
  3. #define nDEBUGA
  4. #define xDEBUGSEQ
  5. #define noDEBUGPKT
  6. #define xDEBUGWR
  7. #define noDEBUGWA
  8. #define nDEBUGS
  9. #define nDEBUGPS
  10. #define noDEBUGRST
  11. #define yDEBUGW
  12. #define nDEBUGRWIN
  13. #define noRTDEBUG
  14. #define noDEBUGPRT
  15. #define xDEBUGTIMEW
  16. #define noDEBUGBUF
  17. #define xDEBUGSENDCALL
  18.  
  19. #define ACKWRONG
  20. #define nREQUEUE
  21.  
  22. #include <stdio.h>
  23.  
  24. #ifdef DEBUG
  25. #include <string.h>
  26. #endif
  27.  
  28. #include <stdlib.h>
  29. #include <time.h>
  30. #include "pktdrv.h"
  31. #include "ip.h"
  32. #include "tcp.h"
  33. #include "timer.h"
  34. #include "inetcust.h"
  35. #include "mbuf.h"
  36.  
  37. #ifdef DEBUG
  38. #include "cookie.h"
  39. #include "nettrace.h"
  40. static char str[200];
  41. #endif
  42.  
  43. #define max(a,b) ((a) > (b) ? (a) : (b))
  44. #define min(a,b) ((a) < (b) ? (a) : (b))
  45. #define abs(a)   ((a) > 0 ? (a) : (-a))
  46.  
  47. TCP_TCB *tcpcb_list = NULL;
  48. TCP_TCB **tcpcb_tab = NULL;
  49. static int tcpcb_tablen = 0;
  50. extern char *tcp_buffers;
  51. int tcpcb_needack = -1;
  52. static TIMER tcp_expedit;
  53. extern int mode;
  54. long tcp_counts[2] = {0L,0L};
  55.  
  56. long INBUFBASE, OUTBUFSIZE;
  57.  
  58. #define tcp_iss()    clock() & 0xffffL;
  59.  
  60. static int tcp_reset(PACKET *,int,INADDR,u_short);
  61. void tcp_opentimeout(TIMER);
  62. void tcp_acktimeout(TIMER);
  63. void tcp_timewait(TIMER);
  64. void tcp_expedittm(TIMER);
  65. static int tcp_send(TCP_TCB *tcpcb);
  66. static TCP_SEGMENT *tcp_createseg(u_long length, u_long seq,u_char flags);
  67. static int tcp_putseg(TCP_TCB *tcpcb,TCP_SEGMENT *tcp_seg);
  68. static int tcp_updateseg(TCP_TCB *tcpcb);
  69. static int tcp_reseg(TCP_TCB *tcpcb);
  70. int tcp_handler(PACKET *pkt, int length, INADDR fhost);
  71. int tcp_du_handler(IP *ip);
  72. u_short tcp_newport(void);
  73. void tcp_retransmitter(TIMER);
  74. u_short tcp_rcvwindow(TCP_TCB *);
  75.  
  76. #ifdef DEBUG
  77. char *pr_flags(u_char);
  78. char *pr_state(TCP_TCB *);
  79. #endif
  80.  
  81. int tcp_init(void)
  82. {
  83.   register int i;
  84.   char *value;
  85.   
  86.   value = (char *)getenv("INBUFBASE");
  87.   if(value) INBUFBASE = atol(value);
  88.   else INBUFBASE = 0L;
  89.   
  90.   value = (char *)getenv("OUTBUFSIZE");
  91.   if(value) OUTBUFSIZE = atol(value);
  92.   else OUTBUFSIZE = MIN_OUTBUFSIZE;
  93.  
  94.   tcpcb_list = NULL;
  95.   tcpcb_tablen = TCP_DEFMAXTCPS;
  96.   tcpcb_tab = (TCP_TCB **)getmem((size_t)tcpcb_tablen*sizeof(TCP_TCB *));
  97.   if(!tcpcb_tab) return(FALSE);
  98.   for(i=0; i<tcpcb_tablen; i++)
  99.     tcpcb_tab[i] = NULL;
  100.   tcpcb_list = NULL;
  101.   if(!ip_open(IP_TCP,tcp_handler,tcp_du_handler))
  102.   {
  103.     freemem(tcpcb_tab);
  104.     return(FALSE);
  105.   }
  106.  
  107.   tcp_expedit = tm_alloc();
  108.   /*
  109.       tm_set(TCP_EXPEDIT,tcp_expedittm,tcp_expedit);
  110.   */
  111.   return(TRUE);
  112. }
  113.  
  114. int tcp_exit(void)
  115. {
  116.   int i;
  117.   if(tcpcb_tab)
  118.   {
  119.     for(i=0;i<tcpcb_tablen;i++)
  120.       if(tcpcb_tab[i]) tcp_delete(i);
  121.     freemem(tcpcb_tab);
  122.     tcpcb_tab = NULL;
  123.     tcpcb_tablen = 0;
  124.   }
  125.   return(ip_close(IP_TCP));
  126. }
  127.  
  128. /********************************/
  129. /* process incoming tcp-packets */
  130. /********************************/
  131.  
  132. int tcp_handler(PACKET *pkt,int len,INADDR fhost)
  133. {
  134.   TCP_PSEUDO    tcp_ph;
  135.   TCP            *tcp;
  136.   IP            *ip;
  137.   TCP_TCB        *tcpcb;
  138.   TCP_SEGMENT    *tcp_seg;
  139.   u_short        csum;
  140.   char *data;
  141.  
  142. #ifdef DEBUG
  143.   TRACE(">tcp_handler\n");
  144. #endif
  145.   ip = ip_head(pkt);
  146.   tcp = (TCP *)ip_data(pkt);
  147.  
  148.   tcp_ph.dst = ip->dst_inaddr;
  149.   tcp_ph.src = fhost;
  150.   tcp_ph.protocol = IP_TCP;
  151.   tcp_ph.length = len;
  152.  
  153.   csum = tcp->chksum;
  154.   tcp->chksum = ~chksum((u_short *)&tcp_ph,(int)sizeof(TCP_PSEUDO),0);
  155.   tcp->chksum = chksum((u_short *)tcp,len,0);
  156.   if(csum != tcp->chksum && !(csum == 0xffff && tcp->chksum == 0))
  157.   {
  158. #ifdef DEBUG
  159.     TRACE("<tcp_handler: bad checksum\n");
  160. #endif
  161.     ip_free(pkt);  /* bad checksum, drop packet */
  162.     return(FALSE);
  163.   }
  164.   tcp->chksum = csum;
  165. #ifdef DEBUGP
  166.   sprintf(str," tcp_handler: to l_%u from f_%u, %s\n",tcp->dst_port,tcp->src_port,pr_flags(tcp->flags));
  167.   TRACE(str);
  168. #endif
  169.   tcp_counts[0]++;
  170.   /* demux to active tcpcb's */
  171.   for(tcpcb = tcpcb_list; tcpcb; tcpcb = tcpcb->next)
  172.   {
  173.     if( tcpcb->active &&
  174.         tcp->dst_port == tcpcb->lcl_port &&
  175.         tcp->src_port == tcpcb->fgn_port &&
  176.         fhost == tcpcb->fhost)
  177.       break;
  178.   }
  179.   if(!tcpcb) for(tcpcb = tcpcb_list; tcpcb; tcpcb = tcpcb->next)
  180.   {  /* demux to listening ports */
  181.     if( !tcpcb->active &&
  182.         tcp->dst_port == tcpcb->lcl_port)
  183.       break;
  184.   }
  185.   if(!tcpcb || tcpcb->state == TCP_CLOSED)
  186.   {  /* no one wants packet */
  187. #ifdef DEBUG
  188.     sprintf(str,"<tcp_handler: ? %lx at port l_%u.f_%u\n",fhost,tcp->dst_port,tcp->src_port);
  189.     TRACE(str);
  190. #endif
  191.     tcp_reset(pkt,len,fhost,tcp->dst_port);  /* send a reset back*/
  192.     ip_free(pkt);
  193.     return(FALSE);
  194.   }
  195. #ifdef DEBUG
  196.   sprintf(str," tcp_handler: l_%u.f_%u: pkt[%d] recnxt=%lx,\n... seq=%lx, fl=%s st=%s\n",tcp->dst_port,tcp->src_port,len,tcpcb->rcvnxt,tcp->seq,pr_flags(tcp->flags),pr_state(tcpcb));
  197.   TRACE(str);
  198. #endif
  199.  
  200.   switch(tcpcb->state)
  201.   {
  202.   case TCP_LISTEN:
  203.     if(tcp->flags & TCP_RST)
  204.     {
  205.       ip_free(pkt);  /* ignore RST packet */
  206.       return(FALSE);
  207.     }
  208.     if(tcp->flags & TCP_ACK)
  209.     {
  210.       tcp_reset(pkt,len,fhost,tcp->dst_port);  /* ack is invalid */
  211.       ip_free(pkt);
  212.       return(FALSE);
  213.     }
  214.     if(tcp->flags & TCP_SYN)
  215.     {
  216. #ifdef DEBUGCONN
  217.       TRACE(" tcp_handler: TCP_LISTEN + SYN received -> SYNREC state\n");
  218. #endif
  219.       tcpcb->rcvnxt = tcp->seq+1;
  220.       tcpcb->sndwnd = tcp->window;
  221.       tcpcb->sndiss = tcp_iss();
  222.       tcpcb->sndact = tcpcb->sndiss;
  223.       tcpcb->fhost = fhost;
  224.       tcpcb->fgn_port = tcp->src_port;
  225.       tcpcb->state = TCP_SYNREC;
  226.       if(tcp_getopt(tcp) < tcpcb->maxseg)
  227.         tcpcb->maxseg = tcp_getopt(tcp);
  228.       tcp_seg = tcp_createseg(0,tcpcb->sndiss,TCP_SYN | TCP_ACK);
  229.       tcp_putseg(tcpcb,tcp_seg);  /* put segment in retransmission queue */
  230. #ifdef DEBUGCONN
  231.       TRACE(" tcp_handler: call send for SYNACK\n");
  232. #endif
  233.       tcp_send(tcpcb);
  234.       tcpcb->sndnxt = tcpcb->sndiss+1;
  235.       tcpcb->snduna = tcpcb->sndiss;
  236.     }
  237.     ip_free(pkt);
  238.     return(TRUE);
  239.  
  240.   case TCP_SYNSENT:
  241.     if(tcp->flags & TCP_ACK)
  242.     {
  243.       if(SEQ_LE(tcp->ack,tcpcb->sndiss) ||
  244.           SEQ_GT(tcp->ack,tcpcb->sndnxt))
  245.       {
  246.         tcp_reset(pkt,len,fhost,tcp->dst_port);  /* ack is invalid */
  247.         ip_free(pkt);
  248.         return(FALSE);
  249.       }
  250.     }
  251.     
  252.     if(tcp->flags & TCP_RST)
  253.     {
  254.       if(tcp->flags & TCP_ACK)
  255.       {
  256.         /*tcpcb->upcall(tcpcb->handle,NULL,TCP_UCRESET);*/
  257.         tm_stop(tcpcb->tcp_tm);
  258. #ifdef DEBUGCONN
  259.         TRACE("<tcp_handler: delete on ACK/RST\n");
  260. #endif
  261.         tcp_delete(tcpcb->handle);
  262.       }
  263.       ip_free(pkt);
  264.       return(FALSE);
  265.     }
  266.     
  267.     if(tcp->flags & TCP_SYN)
  268.     {
  269.       tcpcb->rcvnxt = tcp->seq+1L;
  270.       tcpcb->rcvirs = tcp->seq;
  271.       tcpcb->snduna = tcp->ack;
  272.       tcp_updateseg(tcpcb);
  273.       if(tcp_getopt(tcp) < tcpcb->maxseg)
  274.         tcpcb->maxseg = tcp_getopt(tcp);
  275.       tcpcb->sndwnd = tcp->window;
  276.       if(SEQ_GT(tcpcb->snduna,tcpcb->sndiss))
  277.       {
  278.         tcpcb->state = TCP_ESTAB;
  279.         tcp_seg = tcp_createseg(0,tcpcb->sndnxt,TCP_ACK);
  280.         tcp_putseg(tcpcb,tcp_seg);
  281. #ifdef DEBUGCONN
  282.         TRACE(" tcp_handler: call send for SYNSENTACK\n");
  283. #endif
  284.         tcp_send(tcpcb);
  285.         /*tcpcb->upcall(tcpcb->handle,NULL,TCP_UCESTAB);*/
  286.         tm_stop(tcpcb->tcp_tm);
  287. #ifdef DEBUGCONN
  288.         TRACE(" tcp_handler: TCP_SYNSENT -> entering ESTAB state\n");
  289. #endif
  290.       }
  291.       else
  292.       {
  293.         tcpcb->state = TCP_SYNREC;
  294.         tcp_seg = tcp_createseg(0,tcpcb->sndnxt,TCP_SYN | TCP_ACK);
  295.         tcp_putseg(tcpcb,tcp_seg);  /* put segment in retransmission queue */
  296. #ifdef DEBUGCONN
  297.         TRACE(" tcp_handler: call send for SYNSENTSYNACK\n");
  298. #endif
  299.         tcp_send(tcpcb);
  300. #ifdef DEBUGCONN
  301.         TRACE(" tcp_handler: entering SYNREC state\n");
  302. #endif
  303.       }
  304.     }
  305.     ip_free(pkt);
  306.     return(FALSE);
  307.   }  /* end switch */
  308.  
  309. #ifdef DEBUGCONN
  310.   TRACE(" tcp_handler: more than SYNREC\n");    
  311. #endif
  312.   len -= tcp_hdrlen(tcp);
  313.  
  314.   if(tcp->flags & TCP_RST)
  315.   {
  316.     if(tcpcb->state == TCP_SYNREC)
  317.     {
  318.       if(tcpcb->active)
  319.       {
  320.         /*tcpcb->upcall(tcpcb->handle,NULL,TCP_UCRESET);*/
  321.         tm_stop(tcpcb->tcp_tm);
  322.       }
  323.       else
  324.       {
  325.         tcpcb->state = TCP_LISTEN;
  326.       }
  327.       ip_free(pkt);
  328.       return(FALSE);
  329.     }
  330.     /*tcpcb->upcall(tcpcb->handle,NULL,TCP_UCCLOSED);*/
  331. #ifdef DEBUGCONN
  332.     TRACE("<tcp_handler: delete on RST\n");
  333. #endif
  334.     tcp_delete(tcpcb->handle);
  335.     ip_free(pkt);
  336.     return(FALSE);
  337.   }
  338.  
  339.   if(/*!(tcp->flags & TCP_RST) &&*/ 
  340.       ((!tcpcb->rcvwnd && (len || tcp->seq != tcpcb->rcvnxt)) ||
  341. #ifndef REQUEUE
  342.   (SEQ_GT(tcp->seq,tcpcb->rcvnxt)) ||
  343. #endif
  344.   (len && SEQ_LE((tcp->seq + len),tcpcb->rcvnxt))))
  345.   {
  346. #ifdef DEBUG
  347.     sprintf(str," tcp_handler: seq not expected pkt = %lx: seq= %lx, rcvnxt=%lx, len = %u\n",
  348.     (long)pkt,tcp->seq,tcpcb->rcvnxt,len);
  349.     TRACE(str);
  350. #endif
  351.     ip_free(pkt);
  352.  
  353. #ifdef ACKWRONG
  354.     tcp_seg = tcp_createseg(0,tcpcb->sndnxt,TCP_ACK);
  355.     tcp_putseg(tcpcb,tcp_seg);  /* put segment in retransmission queue */
  356.     tcp_send(tcpcb);
  357. #ifdef DEBUG
  358.     TRACE("<tcp_handler: called send for out of seq nack\n");
  359. #endif
  360. #endif
  361.     return(FALSE);
  362.   }
  363. #ifdef REQUEUE
  364.   if (SEQ_GT(tcp->seq,tcpcb->rcvnxt))
  365.   {
  366. #ifdef DEBUG
  367.     sprintf(str,"<tcp_handler: requeuing packet seq= %lx, rcvnxt=%lx, len = %d\n",tcp->seq,tcpcb->rcvnxt,len);
  368.     TRACE(str);
  369. #endif
  370.     if(!ip_requeue(pkt))  /* put packet to end of receive queue to delay processing */
  371.       ip_free(pkt);     /* all free packets used, so drop this pkt */
  372.     return(FALSE);
  373.   }
  374. #endif
  375.  
  376.   
  377.   if(tcp->flags & TCP_SYN)
  378.   {
  379.     /*tcpcb->upcall(tcpcb->handle,NULL,TCP_UCCLOSED);*/
  380.     /*        TRACE("<tcp_handler: delete on SYN\n");
  381.             tcp_delete(tcpcb->handle);*/
  382.     ip_free(pkt);
  383.     return(FALSE);
  384.   }
  385.   if(!(tcp->flags & TCP_ACK))  /* MISSING ACK */
  386.   {
  387. #ifdef DEBUG
  388.     TRACE("<tcp_handler: missing ACK\n");
  389. #endif
  390.     ip_free(pkt);
  391.     return(FALSE);
  392.   }
  393.   
  394.   if(tcpcb->state == TCP_SYNREC)
  395.   {
  396.     if(SEQ_LE(tcpcb->snduna,tcp->ack) &&
  397.         SEQ_LE(tcp->ack,tcpcb->sndact))
  398.     {
  399. #ifdef DEBUGCONN
  400.       TRACE(" tcp_handler: TCP_SYNREC-> entering ESTAB state\n");
  401. #endif
  402.       tcpcb->state = TCP_ESTAB;
  403.       if(!len)
  404.       {
  405.         tcpcb->active = TRUE;  /* continue processing */
  406.         /*tcpcb->upcall(tcpcb->handle,NULL,TCP_UCESTAB);*/
  407.       }
  408.     }
  409.     else
  410.     {
  411. #ifdef DEBUGCONN
  412.       sprintf(str,"<tcp_handler: TCP_SYNREC invalid ack %lx, sending reset \n",tcp->ack);
  413.       TRACE(str);
  414. #endif
  415.       tcp_reset(pkt,len,fhost,tcp->dst_port);
  416.       ip_free(pkt);  /* invalid ack */
  417.       return(FALSE);
  418.     }
  419.   }
  420.   if(tcpcb->state == TCP_ESTAB      ||
  421.       tcpcb->state == TCP_FINWT1    ||
  422.       tcpcb->state == TCP_FINWT2    || 
  423.       tcpcb->state == TCP_LASTACK   ||
  424.       tcpcb->state == TCP_CLOSING   ||
  425.       tcpcb->state == TCP_CLOSEWT)
  426.   {
  427. #ifdef DEBUG
  428.     sprintf(str," tcp_handler: TCP_ESTAB snd.una = %lx seg.ack=%lx snd.nxt %lx sndact %lx\n",tcpcb->snduna,tcp->ack,tcpcb->sndnxt,tcpcb->sndact);
  429.     TRACE(str);
  430. #endif
  431.     if(SEQ_GT(tcp->ack,tcpcb->sndact))
  432.     {
  433. #ifdef DEBUG
  434.       TRACE(" tcp_handler: peer is acking unsent data !!\n");
  435. #endif
  436.       ip_free(pkt);
  437.       tcp_seg = tcp_createseg(0,tcpcb->sndnxt,TCP_ACK);
  438.       tcp_putseg(tcpcb,tcp_seg);
  439. #ifdef DEBUGCONN
  440.       sprintf(str,"<tcp_handler: call send for unack \n");
  441.       TRACE(str);
  442. #endif
  443.       tcp_send(tcpcb);
  444.       return(FALSE);
  445.     }
  446.  
  447.     if(SEQ_LT(tcpcb->snduna,tcp->ack))  /* new ack arrived */
  448.     {
  449.       tcpcb->snduna = tcp->ack;
  450. /*#ifdef DEBUG
  451.       TRACE(" tcp_handler: update resendqueue on ack\n");
  452. #endif
  453.       tcp_updateseg(tcpcb);  /* update resendqueue */
  454. */
  455.       switch(tcpcb->state)
  456.       {
  457.       case TCP_LASTACK:
  458.         if(tcpcb->snduna == tcpcb->finack)
  459.         {
  460.           /*tcpcb->upcall(tcpcb->handle,NULL,TCP_UCCLOSED);*/
  461. #ifdef DEBUGCONN
  462.           TRACE("<tcp_handler: delete in LASTACK\n");
  463. #endif
  464.           tcp_delete(tcpcb->handle);
  465.         }
  466.       case TCP_CLOSING:
  467.         if(tcpcb->snduna == tcpcb->finack)
  468.         {
  469.           tcpcb->state = TCP_TIMEWT;
  470. #ifdef DEBUGTIMEW
  471.           TRACE(" tcp_handler: TCP_CLOSING ->timewait clock set\n");
  472. #endif
  473.           tm_stop(tcpcb->tcp_tm);
  474.           tm_set(TCP_WAITTIMEOUT,tcp_timewait,tcpcb->tcp_tm);
  475.         }
  476.         break;
  477.       case TCP_FINWT1:
  478.         if(tcpcb->snduna == tcpcb->finack)
  479.           tcpcb->state = TCP_FINWT2;
  480.         break;
  481.       }
  482.     }
  483.  
  484.     if(SEQ_LE(tcpcb->snduna,tcp->ack))
  485.     {
  486.       if(SEQ_LT(tcpcb->sndwl1,tcp->seq) ||
  487.         (tcpcb->sndwl1 == tcp->seq && SEQ_LE(tcpcb->sndwl2,tcp->ack)))
  488.       {
  489.         if(tcpcb->sndmax < tcp->window)
  490.           tcpcb->sndmax = tcp->window;
  491.         tcpcb->sndest = (u_short)(tcpcb->sndact - tcpcb->snduna);
  492.         if(tcp->window > tcpcb->sndest)
  493.           tcpcb->sndest = tcp->window - tcpcb->sndest;
  494.         else
  495.           tcpcb->sndest = 0;
  496.  
  497.         tcpcb->sndwnd = tcp->window;
  498.  
  499.         tcpcb->sndwl1    = tcp->seq;
  500.         tcpcb->sndwl2 = tcp->ack;
  501. #ifdef DEBUGWA
  502.         sprintf(str," tcp_handler: updating sendwindow, now got %d, est %d used %d \n",tcp->window, tcpcb->sndest, tcpcb->sndwnd);
  503.         TRACE(str);
  504. #endif
  505.       }
  506.     }
  507.  
  508.     if( tcpcb->state == TCP_SYNREC || 
  509.         tcpcb->state == TCP_ESTAB  || 
  510.         tcpcb->state == TCP_FINWT1 ||
  511.         tcpcb->state == TCP_FINWT2)
  512.     {
  513.       data = (char *)tcp + tcp_hdrlen(tcp);
  514.       if(SEQ_LT(tcp->seq,tcpcb->rcvnxt) &&
  515.           SEQ_GT(tcp->seq+len,tcpcb->rcvnxt))
  516.       {
  517.         data += tcpcb->rcvnxt - tcp->seq;
  518.         len -= (int)(tcpcb->rcvnxt - tcp->seq);
  519.       }
  520.  
  521.       if(len && tcpcb->q_in.size)
  522.       {
  523.         len = (int)q_put(&tcpcb->q_in,(u_char *)data,len);
  524. #ifdef     DEBUG
  525.         sprintf(str," tcp_handler: queued %d bytes, rd = %lx wr = %lx\n",
  526.         len,(&tcpcb->q_in)->rd,(&tcpcb->q_in)->wr);
  527.         TRACE(str);
  528. #endif
  529.         if(q_used(&tcpcb->q_in) > tcpcb->rcvdlen)
  530.           tcpcb->rcvdlen = q_used(&tcpcb->q_in);
  531.         tcpcb->rcvnxt += len;
  532. #ifdef     DEBUGSEQ
  533.         sprintf(str," tcp_handler: updated rcvnxt, now %lx (+%ld)\n",tcpcb->rcvnxt,(long)len);
  534.         TRACE(str);
  535. #endif
  536.       }
  537.       tcpcb->rcvwnd = tcp_rcvwindow(tcpcb);
  538.  
  539.       if(!tcpcb->active)
  540.       {
  541.         tcpcb->active = TRUE;
  542.         /*tcpcb->upcall(tcpcb->handle,NULL,TCP_UCESTAB);*/
  543.       }
  544.       /*if(tcpcb->q_in.size && len && (tcp->flags & TCP_PUSH 
  545.            || tcpcb->rcvwnd < (tcpcb->q_in.size * 3) / 4))
  546.                       tcpcb->upcall(tcpcb->handle,NULL,TCP_UCDATA)*/;  /* tell user new data is there */
  547.  
  548.       if(len)
  549.       {
  550. #ifdef DEBUG
  551.         TRACE(" tcp_handler: create delayed ack_segment\n");
  552. #endif
  553.         tcp_seg = tcp_createseg(0,tcpcb->sndnxt,TCP_ACK);
  554.         tcp_putseg(tcpcb,tcp_seg);
  555.         tm_stop(tcpcb->tcp_ack);
  556.         tm_stop(tcpcb->tcp_tmresend);
  557.         /*tcp_acktimeout*/(tm_set(TCP_NODELAY,tcp_acktimeout,tcpcb->tcp_ack));
  558.         /* deliver ack immediately after reading IP-TCP input */
  559.       }
  560.     }
  561.   }
  562.  
  563.   if(tcp->flags & TCP_FIN)
  564.   {
  565.     switch(tcpcb->state)
  566.     {
  567.     case TCP_SYNREC:
  568.     case TCP_ESTAB:
  569.       tcpcb->rcvnxt++;  /* consume FIN */
  570.       tcpcb->state = TCP_CLOSEWT;
  571.       /*tcpcb->upcall(tcpcb->handle,NULL,TCP_UCCLOSEWT);*/
  572.       break;
  573.  
  574.     case TCP_FINWT1:
  575.       tcpcb->rcvnxt++;  /* consume FIN */
  576.       if(tcpcb->finack != tcpcb->snduna)
  577.         tcpcb->state = TCP_CLOSING;
  578.       else
  579.       {
  580.         tcpcb->state = TCP_TIMEWT;
  581.         tm_stop(tcpcb->tcp_tm);
  582.         tm_set(TCP_WAITTIMEOUT,tcp_timewait,tcpcb->tcp_tm);
  583.       }
  584.       break;
  585.     case TCP_FINWT2:
  586.       tcpcb->rcvnxt++;  /* consume FIN */
  587.       tcpcb->state = TCP_TIMEWT;
  588.       tm_stop(tcpcb->tcp_tm);
  589.       tm_set(TCP_WAITTIMEOUT,tcp_timewait,tcpcb->tcp_tm);
  590.       break;
  591.     case TCP_TIMEWT:
  592. #ifdef DEBUGTIMEW
  593.       TRACE(" tcp_handler: TCP_FINWT2 -> timewait clock set\n");
  594. #endif
  595.       tm_stop(tcpcb->tcp_tm);
  596.       tm_set(TCP_WAITTIMEOUT,tcp_timewait,tcpcb->tcp_tm);
  597.       break;
  598.     case TCP_CLOSEWT:
  599.     case TCP_CLOSING:
  600.     case TCP_LASTACK:
  601.       /* remain in state */
  602.       break;
  603.     }
  604.     tcp_seg = tcp_createseg(0,tcpcb->sndnxt,TCP_ACK);
  605.     tcp_putseg(tcpcb,tcp_seg);
  606. #ifdef DEBUGSENDCALL
  607.     sprintf(str," tcp_handler: call send for (FIN)ACK \n");
  608.     TRACE(str);
  609. #endif
  610.     tcp_send(tcpcb);
  611.   }
  612.   ip_free(pkt);
  613. #ifdef DEBUG
  614.   TRACE("<tcp_handler\n");
  615. #endif
  616.   return(FALSE);
  617. }
  618.  
  619. static TCP_SEGMENT *tcp_createseg(u_long length,u_long seq, u_char flags)
  620. {
  621.   TCP_SEGMENT *seg;
  622.  
  623. #ifdef DEBUG
  624.   TRACE(">tcp_createseg\n");
  625. #endif
  626.   seg = (TCP_SEGMENT *)getmem(sizeof(TCP_SEGMENT));
  627.   if(!seg)
  628.   {
  629. #ifdef DEBUG
  630.     TRACE("<tcp_createseg, out of mem\n");
  631. #endif
  632.     return(NULL);
  633.   }
  634.   seg->next = NULL;
  635.   seg->seq = seq;
  636.   seg->flags = flags | TCP_UNSENT;
  637.   seg->length = length;
  638. #ifdef DEBUG
  639.   TRACE("<tcp_createseg,ok\n");
  640. #endif
  641.   return(seg);
  642. }
  643.  
  644. int tcp_putseg(TCP_TCB *tcpcb,TCP_SEGMENT *tcp_seg)
  645. {
  646.   TCP_SEGMENT **q;
  647.   u_long    seq;
  648.  
  649. #ifdef DEBUG
  650.   TRACE(">tcp_putseg\n");
  651. #endif
  652.  
  653.   q = &tcpcb->resend;
  654.   if(*q) seq = (*q)->seq;
  655.   while(*q)
  656.   {
  657.     seq += (*q)->length;
  658.     if((*q)->flags & (TCP_SYN | TCP_FIN)) seq++;
  659.  
  660.     if(!((*q)->flags & (TCP_SYN | TCP_PUSH | TCP_FIN)) && 
  661.         tcp_seg->seq == seq)  /* segment can be combined */
  662.     {
  663. #ifdef DEBUG
  664.       sprintf(str," tcp_putseg: combining segments, size %ld, now %ld, flags = %s, seq = %lx\n",(*q)->length, (*q)->length,pr_flags((*q)->flags) + tcp_seg->length,tcp_seg->seq);
  665.       TRACE(str);
  666. #endif
  667.       (*q)->length += tcp_seg->length;
  668.       (*q)->flags |= tcp_seg->flags;
  669.       freemem(tcp_seg);
  670. #ifdef DEBUG
  671.       TRACE("<tcp_putseg\n");
  672. #endif
  673.       return(TRUE);
  674.     }
  675.     q = &((*q)->next);  /* find end of list   */
  676.   }
  677.   *q = tcp_seg;  /* put at end of list */
  678. #ifdef DEBUG
  679.   TRACE("<tcp_putseg\n");
  680. #endif
  681.   return(TRUE);
  682. }
  683.  
  684. static int tcp_updateseg(TCP_TCB *tcpcb)
  685. {
  686.   register TCP_SEGMENT *tcp_seg;
  687.   long         drop;
  688. #ifdef DEBUG
  689.   TRACE(">tcp_updateseg\n");
  690. #endif
  691.  
  692.   if(!tcpcb->resend)
  693.   {
  694. #ifdef DEBUG
  695.     TRACE("<tcp_updateseg: currently no sendqueue\n");
  696. #endif
  697.     return(FALSE);
  698.   }
  699.   
  700.   tcp_seg = tcpcb->resend;
  701.  
  702.   while(tcp_seg)
  703.   {
  704.     if(SEQ_GT(tcpcb->snduna,tcp_seg->seq))  
  705.     {                            /* part or all of segment is acked */
  706.       if(!tcp_seg->length ||
  707.          SEQ_LE(tcp_seg->seq + tcp_seg->length,tcpcb->snduna) )
  708.       {                            /* all of segment is acked */
  709. #ifdef DEBUG
  710.         sprintf(str," tcp_updateseg: skip acked seg len = %ld\n",tcp_seg->length);
  711.         TRACE(str);
  712. #endif
  713.         tcpcb->resend = tcp_seg->next;        /* new start of resend queue */
  714.         if(tcp_seg->length)
  715.           q_rem(&tcpcb->q_out,tcp_seg->length);  /* dequeue acked data */
  716.         freemem(tcp_seg);
  717.         tcp_seg = tcpcb->resend;
  718.       }
  719.       else      /* segment has data, but not all is acked */
  720.       {
  721. #ifdef DEBUG
  722.         TRACE(" tcp_updateseg: skip some acked data\n");
  723. #endif
  724.         drop = tcpcb->snduna - tcp_seg->seq;
  725.         q_rem(&tcpcb->q_out,drop);        /* remove from start of queue */
  726.         tcp_seg->length -= drop;
  727.         tcp_seg->seq = tcpcb->snduna;
  728.         break;                          /* keep segment in queue */
  729.       }
  730.     }
  731.     else break;
  732.   }
  733.   if(!tcpcb->resend) tm_stop(tcpcb->tcp_tmresend);
  734. #ifdef DEBUG
  735.   TRACE("<tcp_updateseg\n");
  736. #endif
  737.  
  738.   return(TRUE);
  739. }
  740.  
  741. static int tcp_send(TCP_TCB *tcpcb)
  742. {
  743.   PACKET    *pkt;
  744.   TCP_PSEUDO tcp_ph;
  745.   TCP_SEGMENT *tcp_seg, **tcp_lastseg;
  746.   TCP        *tcp;
  747.   char     *data;
  748.   u_short csum;
  749.   u_long  length;
  750.   int     ret,send_mult;
  751.   u_long offset;
  752.   int tmpflags;
  753.   int loop;
  754.   
  755. #ifdef VDEBUG
  756.   TRACE(">tcp_send\n");
  757. #endif
  758.  
  759.   if(!tcpcb)  /* tcpcb does not exist */
  760.   {
  761. #ifdef DEBUG
  762.     TRACE("<tcp_send: tcpcb does not exist - exit\n");
  763. #endif
  764.     return(-1);
  765.   }
  766.   
  767. #ifdef DEBUGS
  768.   sprintf(str," tcp_send: l_%u.f_%u\n",tcpcb->lcl_port,tcpcb->fgn_port);
  769.   TRACE(str);
  770. #endif
  771.  
  772.   tcp_updateseg(tcpcb);        /*  remove already acked data */
  773.  
  774.   offset = 0;
  775.   tcp_seg = tcpcb->resend;
  776.   tcp_lastseg = &tcpcb->resend;
  777.  
  778.   while(tcp_seg && SEQ_LT(tcp_seg->seq + tcp_seg->length,tcpcb->sndact))
  779.   {
  780. #ifdef DEBUG
  781.     sprintf(str," tcp_send: skipping already sent segment %lx...%lx < act = %lx\n",tcp_seg->seq,tcp_seg->seq + tcp_seg->length,tcpcb->sndact);
  782.     TRACE(str);
  783. #endif
  784.     offset += tcp_seg->length;
  785.     tcp_lastseg = &tcp_seg->next;
  786.     tcp_seg = tcp_seg->next;
  787.   }
  788.  
  789.   if(!tcp_seg)
  790.   {
  791. #ifdef DEBUG
  792.     TRACE("<tcp_send: nothing to send - exit\n");
  793. #endif
  794.     return(0);
  795.   }
  796.  
  797.   offset += tcpcb->sndact - tcp_seg->seq;
  798.  
  799. #ifdef DEBUG
  800.     sprintf(str," tcp_send: skip %ld sent bytes in segment\n",tcpcb->sndact - tcp_seg->seq);
  801.     TRACE(str);
  802. #endif
  803.   
  804.  for(loop = 0;loop < 4;loop++)
  805.  {
  806.  
  807.   send_mult = 0;
  808.   length = (tcp_seg->seq + tcp_seg->length) - tcpcb->sndact;
  809.  
  810.   if(length > tcpcb->maxseg)
  811.   {
  812.     send_mult = 1;
  813.     length = tcpcb->maxseg;
  814.   }
  815.  
  816.   tmpflags = tcp_seg->flags;
  817.  
  818.   if(length)
  819.   {  /* don't exceed window of partner */
  820.     if(tcpcb->sndwnd == 0)
  821.     {
  822.       length = 1;  /* if window is zero, send at least one databyte */
  823.       tmpflags &= ~(TCP_PUSH | TCP_URG | TCP_FIN);
  824.       send_mult = 0;  /* don't try to overflow peer */
  825.     }
  826.     else
  827.     {
  828.       if(length > tcpcb->sndwnd - (tcpcb->sndact - tcpcb->snduna))
  829.       {
  830. #ifdef DEBUG
  831.       sprintf(str," tcp_send: length exceeds permitted window (%ld) %ld/%ld - truncated \n",tcpcb->sndwnd,length,tcpcb->sndwnd - (tcpcb->sndact - tcpcb->snduna));
  832.       TRACE(str);
  833. #endif
  834.         length = tcpcb->sndwnd - (tcpcb->sndact - tcpcb->snduna);
  835.         tmpflags &= ~(TCP_PUSH | TCP_URG | TCP_FIN);
  836.         send_mult = 0;  /* don't try to overflow peer */
  837.       }
  838.       else
  839.       {
  840.         if( !(tcp_seg->flags & (TCP_PUSH | TCP_FIN)) && 
  841.           length < min(min(tcpcb->maxseg,tcpcb->sndmax/2),tcpcb->q_out.size*3/4)) 
  842.         {
  843. #ifdef DEBUG
  844.         sprintf(str,"<tcp_send: packet delayed len %ld < wnd = %d, max/2 = %d\n",length,tcpcb->sndwnd,tcpcb->sndmax/2);
  845.         TRACE(str);
  846. #endif
  847.           return(0);
  848.         }
  849.       }
  850.     }
  851.   }
  852. #ifdef DEBUG
  853.   else
  854.     TRACE(" tcp_send: empty packet\n");
  855. #endif
  856.  
  857.   pkt = ip_alloc((int)MAXTCPSEG,0);
  858.  
  859.   if(!pkt)
  860.   {
  861. #ifdef DEBUG
  862.     TRACE("<tcp_send no free packet\n");
  863. #endif
  864.     return(-1);  /* no packet free, can't send */
  865.   }
  866. #ifdef DEBUGPKT
  867.   sprintf(str,"tcp_send: allocated pkt at %lx\n",(long)pkt);
  868.   TRACE(str);
  869. #endif
  870.  
  871.   tcp = (TCP *)ip_data(pkt);
  872.   tcp->src_port = tcpcb->lcl_port;
  873.   tcp->dst_port = tcpcb->fgn_port;
  874.   tcp->seq = tcpcb->sndact;
  875.   tcp->ack = tcpcb->rcvnxt;
  876.   tcp->doffs = TCP_DATAOFFS;
  877.  
  878.   if(tmpflags & TCP_SYN)
  879.   {
  880.     tcp->doffs += TCP_DATAOFFSINCR;
  881.     ((TCP_PACKET *)pkt)->opt = tcp_option(TCP_OPTMAXSEG,4,MYMAXTCPSEG);
  882.   }
  883.  
  884.   tcp->flags = (u_char)tmpflags;
  885.   tcp->window = tcpcb->rcvwnd;
  886. #ifdef DEBUG
  887.   sprintf(str," tcp_send: l.%u: len=%lu,sndwnd=%u,rcvwnd=%u,seq=%lx,ack=%lx,sndact=%lx:%s\n",
  888.   tcp->src_port,length,tcpcb->sndwnd,tcp->window,
  889.   tcp->seq,tcp->ack,tcpcb->sndact,pr_flags(tmpflags));
  890.   TRACE(str);
  891. #endif
  892.   if(tcp->flags & TCP_URG) tcp->urgent = 1 /*tcpcb->sndup*/;
  893.   else tcp->urgent = 0;
  894.   if(length)
  895.   {
  896.     data = (char *)tcp + tcp_hdrlen(tcp);
  897. #ifdef DEBUG
  898.   sprintf(str," tcp_send: senddata[0] = %02x\n",*data);
  899.   TRACE(str);
  900. #endif
  901.     q_get(&tcpcb->q_out,(u_char *)data,length,offset);
  902.   }
  903.  
  904.   tcp_ph.dst = tcpcb->fhost;
  905.   tcp_ph.src = ip_myaddr();
  906.   tcp_ph.protocol = IP_TCP;
  907.   tcp_ph.length = tcp_hdrlen(tcp) + length;
  908.  
  909.   tcp->chksum = 0;
  910.   csum = ~chksum((u_short *)&tcp_ph,(int)sizeof(TCP_PSEUDO),0);
  911.   tcp->chksum = chksum((u_short *)tcp,tcp_ph.length,csum);
  912.   if(!tcp->chksum) tcp->chksum = ~tcp->chksum;
  913.  
  914.   tcp_counts[1]++;
  915.   ret = ip_send(IP_TCP,pkt,tcp_ph.length,tcpcb->fhost);
  916.   ip_free(pkt);
  917.  
  918.   tm_stop(tcpcb->tcp_ack);
  919.   tm_stop(tcpcb->tcp_tmresend);
  920.   tm_set(TCP_RETRANSMIT,tcp_retransmitter,tcpcb->tcp_tmresend);
  921.  
  922.   if(ret < 0) 
  923.   {
  924. #ifdef DEBUG
  925.     sprintf(str,"<tcp_send: network error %d\n",ret);
  926.     TRACE(str);
  927. #endif
  928.     return(ret);  /* network error, couldn't send */
  929.   }
  930.  
  931.   tcpcb->sndact += length;
  932.   offset += length;
  933.   if(tmpflags & (TCP_SYN | TCP_FIN))    tcpcb->sndact++;
  934.   if(length == tcp_seg->length) tcp_seg->flags &= ~TCP_UNSENT;
  935.  
  936. #ifdef DEBUG
  937.   sprintf(str," tcp_send: pkt[%d] to %08lx; %s %s\n",
  938.   tcp_ph.length,tcpcb->fhost,pr_flags(tcp_seg->flags),pr_state(tcpcb));
  939.   TRACE(str);
  940. #endif
  941.  
  942.   if((tcp_seg->flags & ~(TCP_PUSH | TCP_URG)) == TCP_ACK && tcp_seg->length == 0)
  943.   {  /* drop a empty ACK segment */
  944. #ifdef DEBUG
  945.   sprintf(str," tcp_send: dropped empty ACK packet,tcp_seg = %lx\n",tcp_seg);
  946.   TRACE(str);
  947. #endif
  948.     tm_stop(tcpcb->tcp_tmresend);
  949.     tcpcb->resend = tcp_seg->next;
  950.     freemem(tcp_seg);
  951.     tcp_seg = tcpcb->resend;
  952.   }
  953.   if(!send_mult) break;
  954.   
  955.  }        /* send again  ?! */
  956.  
  957. #ifdef DEBUG
  958.   TRACE("<tcp_send\n");
  959. #endif
  960.   return(ret);
  961. }
  962.  
  963. static int tcp_reset(PACKET *pkt,int len,INADDR fhost, u_short lcl_port)
  964. {  /* send a reset */
  965.   TCP *tcp;
  966.   TCP_PSEUDO tcp_ph;
  967.   u_short csum;
  968.  
  969. #ifdef DEBUG
  970.   TRACE(">tcp_reset\n");
  971. #endif
  972.   tcp = (TCP *)ip_data(pkt);
  973. #ifdef DEBUG
  974.   sprintf(str,">>tcp_reset.l_%u\n",lcl_port);
  975.   TRACE(str);
  976. #endif
  977.   if(tcp->flags & TCP_RST) return(TRUE); /* received packet has RST */
  978.  
  979.   if(tcp->flags & TCP_ACK)
  980.   {
  981.     tcp->seq = tcp->ack;
  982.     if((tcp->flags & TCP_SYN) || (tcp->flags & TCP_FIN))
  983.       tcp->ack++;
  984.     tcp->flags = TCP_RST;
  985.   }
  986.   else
  987.   {
  988.     tcp->ack = tcp->seq + (u_long)(len - tcp_hdrlen(tcp));
  989.     if(tcp->flags & (TCP_SYN | TCP_FIN))
  990.       tcp->ack++;
  991.     tcp->seq = 0L;
  992.     tcp->flags = TCP_RST | TCP_ACK;
  993.   }
  994.   tcp->dst_port = tcp->src_port;
  995.   tcp->src_port = lcl_port;
  996.  
  997.   tcp_ph.dst = fhost;
  998.   tcp_ph.src = ip_myaddr();
  999.   tcp_ph.protocol = IP_TCP;
  1000.   tcp_ph.length = tcp_hdrlen(tcp);
  1001.  
  1002.   tcp->chksum = 0;
  1003.   csum = ~chksum((u_short *)&tcp_ph,(int)sizeof(TCP_PSEUDO),0);
  1004.   tcp->chksum = chksum((u_short *)tcp,tcp_ph.length,csum);
  1005.   if(!tcp->chksum) tcp->chksum = ~tcp->chksum;
  1006. #ifdef DEBUG
  1007.   TRACE("<>tcp_reset\n");
  1008. #endif
  1009.  
  1010.   tcp_counts[1]++;
  1011.   return(ip_send(IP_TCP,pkt,tcp_ph.length,fhost));
  1012. }
  1013.  
  1014. int tcp_create(long inbuffersize,long outbuffersize,
  1015. TCP_UPCALL upcall)
  1016. {
  1017.   TCP_TCB *tcpcb;
  1018.   int i;
  1019.  
  1020. #ifdef DEBUG
  1021.   TRACE(">tcp_create\n");
  1022. #endif
  1023.   if(!tcpcb_tab)
  1024.   {
  1025. #ifdef DEBUG
  1026.     TRACE("<tcp_create, no tab\n");
  1027. #endif
  1028.     return(-1);
  1029.   }
  1030.   tcpcb = (TCP_TCB *)buf_alloc(tcp_buffers,sizeof(TCP_TCB)+inbuffersize+INBUFBASE+OUTBUFSIZE+2);
  1031.   if(!tcpcb)
  1032.   {
  1033. #ifdef DEBUG
  1034.     TRACE("<tcp_create, no buf\n");
  1035. #endif
  1036.     return(-1);
  1037.   }
  1038.   tcpcb->next = NULL;
  1039.   tcpcb->active = FALSE;
  1040.   tcpcb->lcl_port = 0;
  1041.   tcpcb->fgn_port = 0;
  1042.   tcpcb->state = TCP_CLOSED;
  1043.   tcpcb->fhost = 0L;
  1044.   tcpcb->resend = NULL;
  1045.   q_init(&tcpcb->q_out,((char *)tcpcb)+sizeof(TCP_TCB),OUTBUFSIZE+1);
  1046.   q_init(&tcpcb->q_in,((char *)tcpcb)+sizeof(TCP_TCB)+OUTBUFSIZE+1,inbuffersize+INBUFBASE+1);
  1047.   tcpcb->maxseg = MYMAXTCPSEG;
  1048.   tcpcb->snduna = 0L;
  1049.   tcpcb->sndnxt = 0L;
  1050.   tcpcb->sndact = 0L;
  1051.   tcpcb->sndmax = 0;
  1052.   tcpcb->sndwnd = 0;
  1053.   tcpcb->sndest = 0;
  1054.   tcpcb->sndup = 0L;
  1055.   tcpcb->sndwl1 = 0L;
  1056.   tcpcb->sndwl2 = 0L;
  1057.   tcpcb->sndiss = 0L;
  1058.  
  1059.   tcpcb->rcvnxt = 0L;
  1060.   tcpcb->rcvwnd = (u_short)abs(inbuffersize);
  1061.   tcpcb->rcvact = (u_short)abs(inbuffersize);
  1062.   tcpcb->rcvup = 0;
  1063.   tcpcb->rcvdlen = 0;
  1064.   tcpcb->timeout = 0L;
  1065.   tcpcb->tcp_tm = tm_alloc();
  1066.   tcpcb->tcp_ack = tm_alloc();
  1067.   tcpcb->tcp_tmresend = tm_alloc();
  1068.   tcpcb->upcall = upcall;
  1069.  
  1070.   for(i=0; i<tcpcb_tablen; i++)
  1071.   {
  1072.     if(!tcpcb_tab[i])
  1073.     {
  1074.       tcpcb_tab[i] = tcpcb;
  1075.       tcpcb->handle = i;
  1076. #ifdef DEBUG
  1077.       TRACE("<tcp_create, ok\n");
  1078. #endif
  1079.       return(i);
  1080.     }
  1081.   }
  1082. #ifdef DEBUG
  1083.   TRACE("<tcp_create, error\n");
  1084. #endif
  1085.   return(-1);
  1086. }
  1087.  
  1088. /* assign a number to local port */
  1089. int tcp_bind(int tcpcb,u_short lcl_port)
  1090. {
  1091.   TCP_TCB *ptcpcb;
  1092.  
  1093. #ifdef DEBUG
  1094.   TRACE(">tcp_bind\n");
  1095. #endif
  1096.  
  1097.   if(tcpcb<0 || tcpcb >= tcpcb_tablen) return(-1);
  1098.   for(ptcpcb = tcpcb_list; ptcpcb; ptcpcb = ptcpcb->next)
  1099.     if(ptcpcb->lcl_port == lcl_port)
  1100.     {
  1101.       if(ptcpcb->state == TCP_TIMEWT)
  1102.       {
  1103. #ifdef DEBUG
  1104.         TRACE("<tcp_bind, deleting timewaiting tcpcb\n");
  1105. #endif
  1106.         /*            tcp_delete(ptcpcb->handle);*/
  1107.  
  1108.         /* was passiert eigentlich mit ptcpcb->next wenn ptcpcb gelöscht wird ? */
  1109.       }
  1110.       else
  1111.       {
  1112. #ifdef DEBUG
  1113.         TRACE("<tcp_bind, already in use\n");
  1114. #endif
  1115.         return(-1);
  1116.       }
  1117.     }
  1118.   ptcpcb = tcpcb_tab[tcpcb];
  1119.   if(!ptcpcb || ptcpcb->next || ptcpcb->state != TCP_CLOSED)
  1120.   {
  1121. #ifdef DEBUG
  1122.     TRACE("<tcp_create, not exist\n");
  1123. #endif
  1124.     return(-1);  /* tcpcb does not exist or already in use */
  1125.   }
  1126.  
  1127.   ptcpcb->lcl_port = lcl_port;
  1128. #ifdef DEBUG
  1129.   sprintf(str,">>tcp_bind.l_%u.f_%u\n",ptcpcb->lcl_port,ptcpcb->fgn_port);
  1130.   TRACE(str);
  1131. #endif
  1132. #ifdef DEBUG
  1133.   TRACE("<tcp_bind, ok\n");
  1134. #endif
  1135.   return(tcpcb);
  1136. }
  1137.  
  1138. TCP_TCB *tcp_gettcb(int tcpcb)
  1139. {
  1140.   TCP_TCB *ptcpcb;
  1141.  
  1142.   if(tcpcb<0 || tcpcb >= tcpcb_tablen) return(NULL);
  1143.   ptcpcb = tcpcb_tab[tcpcb];
  1144.   return(ptcpcb);
  1145. }
  1146.  
  1147. int tcp_open(int handle,INADDR fhost,u_short fport,u_long timeout)
  1148. {
  1149.   TCP_TCB *tcpcb;
  1150.   TCP_SEGMENT    *tcp_seg;
  1151.   int ret;
  1152.  
  1153. #ifdef DEBUG
  1154.   sprintf(str,">tcp_open handle %u f_%u tmout %lu, tablen = %d\n",handle,fport,tcpcb_tablen,timeout);
  1155.   TRACE(str);
  1156. #endif
  1157.  
  1158.   if(handle < 0 || handle >= tcpcb_tablen)
  1159.   {
  1160. #ifdef DEBUG
  1161.     TRACE("<tcp_open, inv handle\n");
  1162. #endif
  1163.     return(-1);
  1164.   }
  1165.   tcpcb = tcpcb_tab[handle];
  1166.   if(!tcpcb || tcpcb->next || tcpcb->state != TCP_CLOSED)
  1167.   {
  1168. #ifdef DEBUG
  1169.     TRACE("<tcp_open, not exist\n");
  1170. #endif
  1171.     return(-1);  /* tcpcb does not exist or already in use */
  1172.   }
  1173.   if(!tcpcb->lcl_port) tcpcb->lcl_port = tcp_newport();
  1174.   tcpcb->fgn_port = fport;
  1175.   tcpcb->state = TCP_SYNSENT;
  1176.   tcpcb->fhost = fhost;
  1177.   tcpcb->snduna = tcp_iss();
  1178.   tcpcb->sndnxt = tcpcb->snduna+1;
  1179.   tcpcb->sndact = tcpcb->snduna;
  1180.   tcpcb->sndmax = 0;
  1181.   tcpcb->sndiss = tcpcb->snduna;
  1182.   tcpcb->timeout = timeout;
  1183.   tcpcb->active = TRUE;
  1184.  
  1185. #ifdef DEBUG
  1186.   sprintf(str,">>tcp_open.l_%u.f_%u\n",tcpcb->lcl_port,tcpcb->fgn_port);
  1187.   TRACE(str);
  1188. #endif
  1189.  
  1190.   tcpcb->next = tcpcb_list;  /* put into connections list */
  1191.   tcpcb_list = tcpcb;            
  1192.  
  1193.   tcp_seg = tcp_createseg(0,tcpcb->sndiss,TCP_SYN);
  1194.   tcp_putseg(tcpcb,tcp_seg);  /* put segment in retransmission queue */
  1195.   tm_set(TCP_OPENTIMEOUT,tcp_opentimeout,tcpcb->tcp_tm);
  1196.  
  1197. #ifdef DEBUGSENDCALL
  1198.   sprintf(str,"TCP: call send from line %d\n",__LINE__);
  1199.   TRACE(str);
  1200. #endif
  1201.  
  1202.   ret = tcp_send(tcpcb);
  1203.   if(ret < 0)
  1204.   {
  1205. #ifdef DEBUG
  1206.     TRACE("<tcp_open, network error\n");
  1207. #endif
  1208.     return(ret);
  1209.   }
  1210.  
  1211. #ifdef DEBUG
  1212.   tcpcb = tcpcb_list;
  1213.   TRACE("Open TCBs\n");
  1214.   while(tcpcb)
  1215.   {
  1216.     sprintf(str,"handle = %d, l_%u.f_%u\n",tcpcb->handle,tcpcb->lcl_port,tcpcb->fgn_port);
  1217.     TRACE(str);
  1218.     tcpcb = tcpcb->next;
  1219.   }
  1220. #endif
  1221.  
  1222. #ifdef DEBUG
  1223.   TRACE("<tcp_open, ok\n");
  1224. #endif
  1225.  
  1226.   return(handle);
  1227. }
  1228.  
  1229. void tcp_opentimeout(TIMER tm)
  1230. {
  1231.   int handle;
  1232.  
  1233. #ifdef DEBUG
  1234.   TRACE(">tcp_opentimeout\n");
  1235. #endif
  1236.  
  1237.   for(handle = 0; handle < tcpcb_tablen; handle++)
  1238.     if(tcpcb_tab[handle] && tcpcb_tab[handle]->tcp_tm == tm)
  1239.     {
  1240. #ifdef DEBUG
  1241.       sprintf(str,"opentimeout expired: handle %d\n",handle);
  1242.       TRACE(str);
  1243. #endif
  1244.       /*tcpcb_tab[handle]->upcall(handle,NULL,TCP_UCTIMEOUT);*/
  1245.       tcp_delete(handle);
  1246. #ifdef DEBUG
  1247.       TRACE("<tcp_opentimeout, tcpcb deleted\n");
  1248. #endif
  1249.       return;
  1250.     }
  1251. #ifdef DEBUG
  1252.   TRACE("<tcp_opentimeout, no tcpcb\n");
  1253. #endif
  1254. }
  1255.  
  1256. int tcp_listen(int handle,u_short lcl_port, u_long timeout)
  1257. {
  1258.   TCP_TCB *tcpcb;
  1259.  
  1260. #ifdef DEBUG
  1261.   sprintf(str,">tcp_listen.l_%u\n",lcl_port);
  1262.   TRACE(str);
  1263. #endif
  1264.  
  1265.   if(handle < 0 || handle >= tcpcb_tablen)
  1266.   {
  1267. #ifdef DEBUG
  1268.     TRACE("<tcp_listen, inv handle\n");
  1269. #endif
  1270.     return(-1);
  1271.   }
  1272.   if(!lcl_port)
  1273.     lcl_port = tcp_newport();
  1274.  
  1275.   for(tcpcb = tcpcb_list; tcpcb; tcpcb = tcpcb->next)
  1276.     if(!tcpcb->active && tcpcb->lcl_port == lcl_port)
  1277.     {
  1278. #ifdef DEBUG
  1279.       TRACE("<tcp_listen, port in use\n");
  1280. #endif
  1281.       return(-1);
  1282.     }
  1283.   tcpcb = tcpcb_tab[handle];
  1284.   if(!tcpcb || tcpcb->next || tcpcb->state != TCP_CLOSED)
  1285.   {
  1286. #ifdef DEBUG
  1287.     TRACE("tcp_listen, tcpcb not exist\n");
  1288. #endif
  1289.     return(-1);  /* tcpcb does not exist or already in use */
  1290.   }
  1291.   tcpcb->active = FALSE;
  1292.   tcpcb->lcl_port = lcl_port;
  1293.   tcpcb->fgn_port = 0;
  1294.   tcpcb->state = TCP_LISTEN;
  1295.   tcpcb->fhost = 0L;
  1296.   tcpcb->timeout = timeout;
  1297.   if(timeout) tm_set(tm_msec(timeout),tcp_opentimeout,tcpcb->tcp_tm);
  1298.  
  1299.   tcpcb->next = tcpcb_list;
  1300.   tcpcb_list = tcpcb;  /* put into connections list */
  1301. #ifdef DEBUG
  1302.   tcpcb = tcpcb_list;
  1303.   TRACE("Listen TCBs\n");
  1304.   while(tcpcb)
  1305.   {
  1306.     sprintf(str,"handle = %d, port l_%u.f_%u\n",tcpcb->handle,tcpcb->lcl_port,tcpcb->fgn_port);
  1307.     TRACE(str);
  1308.     tcpcb = tcpcb->next;
  1309.   }
  1310. #endif
  1311. #ifdef DEBUG
  1312.   TRACE("<tcp_listen, ok\n");
  1313. #endif
  1314.   return(handle);
  1315. }
  1316.  
  1317. int tcp_delete(int tcpcb)
  1318. {
  1319.   TCP_SEGMENT *seg, *tcp_seg;
  1320.   TCP_TCB **b,*ptcpcb;
  1321.  
  1322. #ifdef DEBUG
  1323.   TRACE("<tcp_delete\n");
  1324. #endif
  1325.  
  1326.   if(tcpcb<0 || tcpcb >= tcpcb_tablen)
  1327.   {
  1328. #ifdef DEBUG
  1329.     TRACE("<tcp_delete, inv handle\n");
  1330. #endif
  1331.     return(-1);
  1332.   }
  1333.   ptcpcb = tcpcb_tab[tcpcb];
  1334.   if(!ptcpcb)
  1335.   {
  1336. #ifdef DEBUG
  1337.     TRACE("<tcp_delete, tcpcb does not exist\n");
  1338. #endif
  1339.     return(-1);  /* tcpcb does not exist */
  1340.   }
  1341. #ifdef DEBUG
  1342.   sprintf(str,">>tcp_delete.l_%u.f_%u\n",ptcpcb->lcl_port,ptcpcb->fgn_port);
  1343.   TRACE(str);
  1344. #endif
  1345.   tcpcb_tab[tcpcb] = NULL;
  1346.   tcp_seg = ptcpcb->resend;
  1347.   while(tcp_seg)
  1348.   {
  1349.     seg = tcp_seg->next;
  1350.     freemem(tcp_seg);  /* free all pending segments */
  1351.     tcp_seg = seg;
  1352.   }
  1353.   tm_free(ptcpcb->tcp_tm);  /* free timer */
  1354.   tm_free(ptcpcb->tcp_ack);  /* free timer */
  1355.   tm_free(ptcpcb->tcp_tmresend);  /* free resend timer */
  1356.   b = &tcpcb_list;
  1357.   while(*b)
  1358.   {
  1359.     if(*b == ptcpcb) break;
  1360.     b = &(*b)->next;
  1361.   }
  1362.   if(*b) *b = (*b)->next;
  1363.   if(!buf_free(tcp_buffers,(char *)ptcpcb))
  1364. #ifdef DEBUGBUF
  1365.     TRACE("TCP: buf_free failed\n");
  1366. #endif    
  1367.   ;  /* free control block */
  1368. #ifdef DEBUG
  1369.   ptcpcb = tcpcb_list;
  1370.   TRACE("Remaining TCBs\n");
  1371.   while(ptcpcb)
  1372.   {
  1373.     sprintf(str,"handle = %d, port l_%u.f_%u\n",ptcpcb->handle,ptcpcb->lcl_port,ptcpcb->fgn_port);
  1374.     TRACE(str);
  1375.     ptcpcb = ptcpcb->next;
  1376.   }
  1377. #endif
  1378. #ifdef DEBUG
  1379.   TRACE("<tcp_delete, ok\n");
  1380. #endif
  1381.   return(TRUE);
  1382. }
  1383.  
  1384. int tcp_close(int tcpcb)
  1385. {
  1386.   TCP_TCB *ptcpcb;
  1387.   TCP_SEGMENT *tcp_seg;
  1388.  
  1389. #ifdef DEBUG
  1390.   TRACE(">tcp_close\n");
  1391. #endif
  1392.  
  1393.   if(tcpcb < 0 || tcpcb >= tcpcb_tablen)
  1394.   {
  1395. #ifdef DEBUG
  1396.     TRACE("<tcp_close, inv handle\n");
  1397. #endif
  1398.     return(-1);
  1399.   }
  1400.   ptcpcb = tcpcb_tab[tcpcb];
  1401.   if(!ptcpcb)
  1402.   {
  1403. #ifdef DEBUG
  1404.     TRACE("<tcp_close, tcpcb does not exist\n");
  1405. #endif
  1406.     return(-1);  /* tcpcb does not exist */
  1407.   }
  1408. #ifdef DEBUG
  1409.   sprintf(str,">>tcp_close.l_%u.f_%u\n",ptcpcb->lcl_port,ptcpcb->fgn_port);
  1410.   TRACE(str);
  1411.   TRACE(pr_state(ptcpcb));
  1412. #endif
  1413.  
  1414.   switch(ptcpcb->state)
  1415.   {
  1416.   case TCP_LISTEN:
  1417.   case TCP_SYNSENT:
  1418.     /*ptcpcb->upcall(tcpcb,NULL,TCP_UCCLOSING);*/
  1419.     tcp_delete(tcpcb);
  1420. #ifdef DEBUG
  1421.     TRACE("<tcp_close, LISTEN or SYNSENT state, tcpcb deleted\n");
  1422. #endif
  1423.     return(FALSE);
  1424.  
  1425.   case TCP_SYNREC:
  1426.   case TCP_ESTAB:
  1427.   case TCP_CLOSEWT:
  1428.     tcp_seg = tcp_createseg(0,ptcpcb->sndnxt++,TCP_FIN | TCP_ACK);
  1429.     ptcpcb->finack = ptcpcb->sndnxt;
  1430.     tcp_putseg(ptcpcb,tcp_seg);
  1431. #ifdef DEBUGSENDCALL
  1432.     sprintf(str,"TCP: call send from line %d\n",__LINE__);
  1433.     TRACE(str);
  1434. #endif
  1435.     tcp_send(ptcpcb);
  1436.     if(ptcpcb->state == TCP_CLOSEWT)
  1437.     {
  1438.       ptcpcb->state = TCP_LASTACK;
  1439. #ifdef DEBUG
  1440.       TRACE("<tcp_close, -> TCP_LASTACK\n");
  1441. #endif
  1442.     }
  1443.     else
  1444.     {
  1445.       ptcpcb->state = TCP_FINWT1;
  1446.       printf("\a");
  1447. #ifdef DEBUG
  1448.       TRACE("<tcp_close, -> TCP_FINWT1\n");
  1449. #endif
  1450.     }
  1451.     return(TRUE);
  1452.  
  1453.   default:
  1454. #ifdef DEBUG
  1455.     TRACE("<tcp_close, already closing\n");
  1456. #endif
  1457.     return(-1);  /* error, closing */
  1458.   }
  1459. }
  1460.  
  1461. int tcp_abort(int tcpcb)
  1462. {
  1463.   PACKET *pkt;
  1464.   TCP_TCB *ptcpcb;
  1465.   TCP *tcp;
  1466.  
  1467. #ifdef DEBUG
  1468.   TRACE(">tcp_abort\n");
  1469. #endif
  1470.  
  1471.   if(tcpcb<0 || tcpcb >= tcpcb_tablen)
  1472.   {
  1473. #ifdef DEBUG
  1474.     TRACE("<tcp_abort, inv handle\n");
  1475. #endif
  1476.     return(-1);
  1477.   }
  1478.   ptcpcb = tcpcb_tab[tcpcb];
  1479.   if(!ptcpcb || ptcpcb->state == TCP_CLOSED)
  1480.   {
  1481. #ifdef DEBUG
  1482.     TRACE("<tcp_abort, tcpcb does not exist\n");
  1483. #endif
  1484.     return(-1);  /* tcpcb does not exist */
  1485.   }
  1486. #ifdef DEBUG
  1487.   sprintf(str,">>tcp_abort.l_%u.f_%u\n",ptcpcb->lcl_port,ptcpcb->fgn_port);
  1488.   TRACE(str);
  1489. #endif
  1490.   switch(ptcpcb->state)
  1491.   {
  1492.   case TCP_SYNREC:
  1493.   case TCP_ESTAB:
  1494.   case TCP_FINWT1:
  1495.   case TCP_FINWT2:
  1496.   case TCP_CLOSEWT:
  1497.     pkt = ip_alloc((int)sizeof(TCP),0);
  1498.     if(pkt)
  1499.     {
  1500. #ifdef DEBUG
  1501.     sprintf(str,"aborting connection to 0x%08lx.l_%d\n",ptcpcb->fhost,ptcpcb->lcl_port);
  1502.     TRACE(str);
  1503. #endif
  1504.     tcp = (TCP *)ip_data(pkt);
  1505.     tcp->flags = TCP_ACK;
  1506.     tcp->src_port = ptcpcb->fgn_port;
  1507.     tcp_reset(pkt,(int)sizeof(TCP),ptcpcb->fhost,ptcpcb->lcl_port);
  1508.     ip_free(pkt);
  1509.     }
  1510.     else return(-1);
  1511.     break;
  1512.   }
  1513.   tcp_delete(tcpcb);
  1514. #ifdef DEBUG
  1515.   TRACE("<tcp_abort, tcpcb deleted\n");
  1516. #endif
  1517.   return(TRUE);
  1518. }
  1519.  
  1520. long tcp_read(int tcpcb,char *buffer,u_short length)
  1521. {
  1522.   TCP_TCB *ptcpcb;
  1523.   TCP_SEGMENT *tcp_seg;
  1524.   long len;
  1525.   u_short cur_rcvwnd;
  1526.  
  1527. #ifdef DEBUG
  1528.   TRACE(">tcp_read\n");
  1529. #endif
  1530.  
  1531.   if(tcpcb < 0 || tcpcb >= tcpcb_tablen)
  1532.   {
  1533.  
  1534. #ifdef DEBUG
  1535.     TRACE("<tcp_read, inv handle\n");
  1536. #endif
  1537.     return(-1L);
  1538.   }
  1539.   ptcpcb = tcpcb_tab[tcpcb];
  1540.   if(!ptcpcb)
  1541.   {
  1542. #ifdef DEBUG
  1543.     TRACE("<tcp_read, tcpcb does not exist\n");
  1544. #endif
  1545.     return(-1L);  /* tcpcb does not exist or already in use */
  1546.  
  1547.   }
  1548. #ifdef DEBUG
  1549.   sprintf(str," tcp_read: l_%u.f_%u\n",ptcpcb->lcl_port,ptcpcb->fgn_port);
  1550.   TRACE(str);
  1551. #endif
  1552.  
  1553.   cur_rcvwnd = ptcpcb->rcvwnd;
  1554.  
  1555.   switch(ptcpcb->state)
  1556.   {
  1557.   case TCP_CLOSED:
  1558.     return(-2L);
  1559.  
  1560.   case TCP_LISTEN:
  1561.   case TCP_SYNSENT:
  1562.   case TCP_SYNREC:
  1563.     return(0L);
  1564.  
  1565.   case TCP_ESTAB:
  1566.   case TCP_FINWT1:    
  1567.   case TCP_FINWT2:
  1568.   case TCP_CLOSEWT:    
  1569.     len = q_used(&ptcpcb->q_in);
  1570. #ifdef     DEBUG
  1571.     sprintf(str," tcp_read: rd = %lx wr = %lx -> %ld bytes in queue\n",(&ptcpcb->q_in)->rd,(&ptcpcb->q_in)->wr,len);
  1572.     TRACE(str);
  1573. #endif
  1574.  
  1575.     if(!len && !ptcpcb->resend)
  1576.     {
  1577. /*     ptcpcb->rcvwnd = tcp_rcvwindow(ptcpcb);
  1578.       tcp_seg = tcp_createseg(0,ptcpcb->sndnxt,TCP_ACK);
  1579.       tcp_putseg(ptcpcb,tcp_seg);
  1580.       tm_stop(ptcpcb->tcp_tmresend);
  1581.       tm_set(TCP_RETRANSMIT,tcp_retransmitter,ptcpcb->tcp_tmresend);*/
  1582.  
  1583. #ifdef DEBUG
  1584.       TRACE("<tcp_read, no data\n");
  1585. #endif
  1586.       if(ptcpcb->state == TCP_CLOSEWT)
  1587.         return(-1L);  /* EOF */
  1588.       else
  1589.         return(0L);
  1590.     }
  1591. #ifdef DEBUG
  1592.     TRACE(" tcp_read: get data\n");
  1593. #endif
  1594.  
  1595.     if(len < length) length = (u_short)len;
  1596.     q_get(&ptcpcb->q_in,(u_char *)buffer,length,0);
  1597.     q_rem(&ptcpcb->q_in,length);
  1598.  
  1599.     ptcpcb->rcvwnd = tcp_rcvwindow(ptcpcb);
  1600.     ptcpcb->rcvdlen = q_used(&ptcpcb->q_in);
  1601.  
  1602.     if(cur_rcvwnd == 0 && ptcpcb->rcvwnd != 0)
  1603.     {
  1604. #ifdef DEBUG
  1605.       TRACE(" tcp_read: create ackseg\n");
  1606. #endif
  1607.       tcp_seg = tcp_createseg(0,ptcpcb->sndnxt,TCP_ACK);
  1608.       tcp_putseg(ptcpcb,tcp_seg);
  1609.       tm_stop(ptcpcb->tcp_ack);
  1610.       /*tcp_acktimeout*/(tm_set(TCP_NODELAY,tcp_acktimeout,ptcpcb->tcp_ack));
  1611.       /* send immediate ack */
  1612.  
  1613.     }
  1614. #ifdef DEBUG
  1615.     TRACE("<tcp_read, ok\n");
  1616. #endif
  1617.     return((long)length);
  1618.  
  1619.   case TCP_CLOSING:
  1620.   case TCP_LASTACK:
  1621.   case TCP_TIMEWT:
  1622.     return(-2L);
  1623.   }
  1624.   return(-2L);
  1625. }
  1626.  
  1627. long tcp_write(int tcpcb,char *buffer,u_short length, u_char flags)
  1628. {
  1629.   TCP_TCB *ptcpcb;
  1630.   TCP_SEGMENT    *tcp_seg;
  1631.   long len;
  1632.   int ret;
  1633.  
  1634. #ifdef DEBUG
  1635.   TRACE(">tcp_write\n");
  1636. #endif
  1637.  
  1638.   flags &= (TCP_PUSH | TCP_URG);
  1639.   if(tcpcb<0 || tcpcb >= tcpcb_tablen)
  1640.   {
  1641. #ifdef DEBUG
  1642.     TRACE("<tcp_write, inv handle\n");
  1643. #endif
  1644.     return(-1L);
  1645.   }
  1646.   ptcpcb = tcpcb_tab[tcpcb];
  1647.   if(!ptcpcb || ptcpcb->state == TCP_CLOSED)
  1648.   {
  1649. #ifdef DEBUG
  1650.     TRACE("<tcp_write, tcpcb does not exist\n");
  1651. #endif
  1652.     return(-1L);  /* tcpcb does not exist or already in use */
  1653.   }
  1654. #ifdef DEBUG
  1655.   sprintf(str," >>tcp_write: l_%u.f_%u %d bytes\n",ptcpcb->lcl_port,ptcpcb->fgn_port,length);
  1656.   TRACE(str);
  1657. #endif
  1658.   if(q_free(&ptcpcb->q_out) < length)
  1659.   {
  1660.     length = q_free(&ptcpcb->q_out);
  1661.     flags &= ~TCP_PUSH;
  1662. #ifdef DEBUG
  1663.     TRACE("<tcp_write:putbuffer full\n");
  1664. #endif
  1665.   }
  1666.   if(length == 0 && !(flags & TCP_URG))  return 0L;
  1667.  
  1668. #ifdef DEBUG
  1669.   sprintf(str," tcp_write: try to send %u bytes\n",length);
  1670.   TRACE(str);
  1671. #endif
  1672.   switch(ptcpcb->state)
  1673.   {
  1674.   case TCP_LISTEN:
  1675.  
  1676.   case TCP_SYNSENT:
  1677.   case TCP_SYNREC:
  1678. #ifdef DEBUG
  1679.     TRACE("<tcp_write, inv state, send not allowed\n");
  1680. #endif
  1681.     return(-1L);
  1682.  
  1683.   case TCP_ESTAB:
  1684.   case TCP_CLOSEWT:
  1685.     len = length;
  1686.     tcp_seg = tcp_createseg(len,ptcpcb->sndnxt,TCP_ACK | flags);
  1687.     if(!tcp_seg)
  1688.     {
  1689. #ifdef DEBUG
  1690.       TRACE("<tcp_write, cannot create segment\n");
  1691. #endif
  1692.       return(0L);
  1693.     }
  1694. #ifdef DEBUG
  1695.     sprintf(str," tcp_write: put segment: %ld bytes senddata[0]=%02x seq=%lx\n",len,buffer[0],ptcpcb->sndnxt);
  1696.     TRACE(str);
  1697. #endif
  1698.     tcp_putseg(ptcpcb,tcp_seg);
  1699.     q_put(&ptcpcb->q_out,(u_char *)buffer,len);
  1700.     ptcpcb->sndnxt += len;
  1701.  
  1702.     if((flags & TCP_PUSH) || (q_free(&ptcpcb->q_out) < (ptcpcb->q_out.size / 4)))
  1703.     {
  1704. #ifdef DEBUGSENDCALL
  1705.       sprintf(str,"TCP: call send from line %d\n",__LINE__);
  1706.       TRACE(str);
  1707. #endif
  1708.       ret = tcp_send(ptcpcb);  /* resend can't be NULL */
  1709.       if(ret < 0)
  1710.       {
  1711. #ifdef DEBUG
  1712.         TRACE("<tcp_write, error\n");
  1713. #endif
  1714.         return((long)ret);  /* report error */
  1715.       }
  1716.     }
  1717. #ifdef DEBUG
  1718.     TRACE("<tcp_write, ok\n");
  1719. #endif
  1720.     return(length);
  1721.  
  1722.   default:
  1723. #ifdef DEBUG
  1724.     TRACE("<tcp_write, error, already closing\n");
  1725. #endif
  1726.     return(-1L);
  1727.   }
  1728. }
  1729.  
  1730. u_short tcp_newport(void)
  1731. {
  1732.   static u_short act_port = 0;
  1733.   TCP_TCB *ptcpcb;
  1734.  
  1735. #ifdef DEBUG
  1736.   TRACE(">tcp_newport\n");
  1737. #endif
  1738.   do
  1739.   {
  1740.     if(!act_port)
  1741.       act_port = (u_short)clock();
  1742.     else 
  1743.         act_port++;
  1744.     if(act_port < 1200) act_port += 1200;
  1745.     for(ptcpcb = tcpcb_list; ptcpcb; ptcpcb = ptcpcb->next)  /* search, if port locally used */
  1746.       if(ptcpcb->lcl_port == act_port) break;
  1747.   }
  1748.   while(ptcpcb);
  1749.  
  1750. #ifdef DEBUG
  1751.   TRACE("<tcp_newport\n");
  1752. #endif
  1753.   return(act_port);
  1754. }
  1755.  
  1756. void tcp_retransmitter(TIMER tm)
  1757. {
  1758.   TCP_TCB *tcpcb;
  1759. #ifdef DEBUG
  1760.   sprintf(str,">tcp_retransmitter %d\n",mode);
  1761.   TRACE(str);
  1762. #endif
  1763.  
  1764.   for(tcpcb = tcpcb_list; tcpcb; tcpcb = tcpcb->next)
  1765.   {
  1766.     if(tm == tcpcb->tcp_tmresend && tcpcb->resend)
  1767.     {
  1768.       tcpcb->sndact = tcpcb->snduna;  /* back off to start of retransmit queue */
  1769. #ifdef DEBUG
  1770.       sprintf(str," retransmit for handle %d\n",tcpcb->handle);
  1771.       TRACE(str);
  1772. #endif
  1773. #ifdef DEBUGSENDCALL
  1774.       sprintf(str," tcpretransmit: call send for l_%ud f_%ud\n",tcpcb->lcl_port,tcpcb->fgn_port);
  1775.       TRACE(str);
  1776. #endif
  1777.       tcp_send(tcpcb);
  1778. #ifdef DEBUG
  1779.       TRACE("<tcp_retransmitter, ok\n");
  1780. #endif
  1781.       return;
  1782.     }
  1783.   }
  1784. #ifdef DEBUG
  1785.   sprintf(str,"<tcp_retransmitter.timer_%u, tcpcb not found\n",tm);
  1786.   TRACE(str);
  1787. #endif
  1788. }
  1789.  
  1790. void tcp_acktimeout(TIMER tm)
  1791. {
  1792.   TCP_TCB *tcpcb;
  1793.  
  1794. #ifdef DEBUG
  1795.   TRACE(">tcp_acktimeout\n");
  1796. #endif
  1797.  
  1798.   for(tcpcb = tcpcb_list; tcpcb; tcpcb = tcpcb->next)
  1799.   {
  1800.     if(tcpcb->tcp_ack == tm)
  1801.     {
  1802. #ifdef DEBUGSENDCALL
  1803.       sprintf(str,"tcpacktimeout: call send for l_%ud f_%ud\n",tcpcb->lcl_port,tcpcb->fgn_port);
  1804.       TRACE(str);
  1805. #endif
  1806.       tcp_send(tcpcb);
  1807. #ifdef DEBUG
  1808.       TRACE("<tcp_acktimeout, ok\n");
  1809. #endif
  1810.       return;
  1811.     }
  1812.   }
  1813. #ifdef DEBUG
  1814.   sprintf(str,"<tcp_acktimeout.timer_%u: tcpcb not found\n",tm);
  1815.   TRACE(str);
  1816. #endif
  1817. }
  1818.  
  1819. void tcp_expedittm(TIMER tm)
  1820. {
  1821.   TCP_TCB *tcpcb;
  1822. #ifdef DEBUG
  1823.   TRACE(">tcp_expedittm\n");
  1824. #endif
  1825.  
  1826.   tcpcb = tcpcb_list;
  1827.   while(tcpcb)
  1828.   {
  1829.     if(tcpcb->resend)
  1830.     {
  1831. #ifdef DEBUGSENDCALL
  1832.       sprintf(str,"tcpexpedit: call send for l_%ud f_%ud\n",tcpcb->lcl_port,tcpcb->fgn_port);
  1833.       TRACE(str);
  1834. #endif
  1835.       tcp_send(tcpcb);
  1836.     }
  1837.     tcpcb = tcpcb->next;
  1838.   }
  1839.   tm_set(TCP_EXPEDIT,tcp_expedittm,tm);
  1840. #ifdef DEBUG
  1841.   TRACE("<tcp_expedittm, ok\n");
  1842. #endif
  1843. }
  1844.  
  1845. void tcp_timewait(TIMER tm)
  1846. {
  1847.   TCP_TCB *tcpcb;
  1848. #ifdef DEBUG
  1849.   TRACE(">tcp_timewait\n");
  1850. #endif
  1851.   for(tcpcb = tcpcb_list; tcpcb; tcpcb = tcpcb->next)
  1852.   {
  1853.     if(tcpcb->state == TCP_TIMEWT && tcpcb->tcp_tm == tm)
  1854.     {
  1855.       /*tcpcb->upcall(tcpcb->handle,NULL,TCP_UCCLOSED);*/
  1856.       tcp_delete(tcpcb->handle);
  1857. #ifdef DEBUGTIMEW
  1858.       sprintf(str,"TCP: timewait tcpcb handle %d deleted\n",tcpcb->handle);
  1859.       TRACE(str);
  1860. #endif
  1861.       return;
  1862.     }
  1863.   }
  1864. #ifdef DEBUG
  1865.   TRACE("tcp_timewait,  no tcpcb found\n");
  1866. #endif
  1867. }
  1868.  
  1869. u_short tcp_rcvwindow(TCP_TCB *tcpcb)
  1870. {
  1871.   short win;
  1872.   u_short mywind;
  1873.   
  1874. #ifdef DEBUGRWIN
  1875.   sprintf(str,">tcp_rcvwindow.l_%u.f_%u qsize=%ul\n",tcpcb->lcl_port,tcpcb->fgn_port,tcpcb->q_in.size);
  1876.   TRACE(str);
  1877. #endif
  1878.  
  1879.   mywind = tcpcb->rcvact = (u_short)q_free(&(tcpcb->q_in));
  1880.  
  1881.   win = tcpcb->rcvact - tcpcb->rcvwnd;
  1882.   
  1883.   if(win > 0)    /* more space */
  1884.   {
  1885.     if(win < MYMAXTCPSEG && MYMAXTCPSEG < tcpcb->q_in.size)
  1886.     {
  1887. #ifdef DEBUGRWIN
  1888.   sprintf(str,"<tcp_rcvwindow rcvact=%u rcvwnd=%u delta=%u new =%u\n",tcpcb->rcvact,tcpcb->rcvwnd,win,tcpcb->rcvwnd);
  1889.   TRACE(str);
  1890. #endif
  1891.       return(tcpcb->rcvwnd);
  1892.     }else
  1893.     {
  1894. #ifdef DEBUGRWIN
  1895.   sprintf(str,"<tcp_rcvwindow rcvact=%u rcvwnd=%u delta=%u new =%u\n",tcpcb->rcvact,tcpcb->rcvwnd,win,tcpcb->rcvwnd + (min(MYMAXTCPSEG, win)));
  1896.   TRACE(str);
  1897. #endif
  1898.      mywind = tcpcb->rcvwnd + (min(MYMAXTCPSEG, win));
  1899.      mywind = min(mywind,(tcpcb->q_in.size - INBUFBASE - 1));  /* hold receive window artificially closed */
  1900.      return mywind;
  1901.     } 
  1902.   }
  1903.   else
  1904.   {
  1905.     if(MYMAXTCPSEG < tcpcb->q_in.size)
  1906.     {
  1907. #ifdef DEBUGRWIN
  1908.   sprintf(str,"<tcp_rcvwindow rcvact=%u rcvwnd=%u delta=%u new =%u\n",tcpcb->rcvact,tcpcb->rcvwnd,win,MYMAXTCPSEG*(tcpcb->rcvact / MYMAXTCPSEG));
  1909.   TRACE(str);
  1910. #endif
  1911.       return(MYMAXTCPSEG*(tcpcb->rcvact / MYMAXTCPSEG));
  1912.     }
  1913.     else
  1914.     {
  1915. #ifdef DEBUGRWIN
  1916.   sprintf(str,"<tcp_rcvwindow rcvact=%u rcvwnd=%u delta=%u new =%u\n",tcpcb->rcvact,tcpcb->rcvwnd,win,tcpcb->rcvact);
  1917.   TRACE(str);
  1918. #endif
  1919.       return(tcpcb->rcvact);
  1920.     }
  1921.   }
  1922. }
  1923.  
  1924. int tcp_du_handler(IP *ip)
  1925. {
  1926.   TCP_TCB *ptcpcb;
  1927.   TCP        *tcp;
  1928.  
  1929. #ifdef DEBUG
  1930.   TRACE(">tcp_du_handler\n");
  1931. #endif
  1932.  
  1933.   if(!ip)
  1934.   {
  1935. #ifdef DEBUG
  1936.     TRACE("<tcp_du_handler, invalid ip\n");
  1937. #endif
  1938.     return(FALSE);
  1939.   }
  1940.   tcp = (TCP *)((char *)(ip)+ip_hdrlen(ip));
  1941.   ptcpcb = tcpcb_list;
  1942.   while(ptcpcb)
  1943.   {
  1944.     if((ip->dst_inaddr == ptcpcb->fhost) &&
  1945.         (ip->src_inaddr == ip_myaddr()) &&
  1946.         (tcp->src_port == ptcpcb->lcl_port) &&
  1947.         (tcp->dst_port == ptcpcb->fgn_port))
  1948.     {
  1949.       tcp_delete(ptcpcb->handle);
  1950. #ifdef DEBUG
  1951.       TRACE("<tcp_du_handler, killed\n");
  1952. #endif
  1953.       return(TRUE);
  1954.     }
  1955.     ptcpcb = ptcpcb->next;
  1956.   }    
  1957. #ifdef DEBUG
  1958.   TRACE("<tcp_du_handler, not found\n");
  1959. #endif
  1960.   return(FALSE);
  1961. }
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970. #ifdef DEBUG
  1971.  
  1972.  
  1973. char *pr_flags(u_char flags)
  1974. {
  1975.   static char pr_str[40];
  1976.   pr_str[0] = 0;
  1977.   if(flags & TCP_FIN) strcat(pr_str,"FIN ");
  1978.   if(flags & TCP_SYN) strcat(pr_str,"SYN ");
  1979.   if(flags & TCP_RST) strcat(pr_str,"RST ");
  1980.   if(flags & TCP_PUSH) strcat(pr_str,"PUSH ");
  1981.   if(flags & TCP_ACK) strcat(pr_str,"ACK ");
  1982.   if(flags & TCP_URG) strcat(pr_str,"URG ");
  1983.   return(pr_str);
  1984. }
  1985.  
  1986. char *pr_state(TCP_TCB *tcpcb)
  1987. {
  1988.   static char *states[11]=
  1989.       {
  1990.     "CLOSED",
  1991.     "LISTEN",
  1992.     "SYNSENT",
  1993.     "SYNREC",
  1994.     "ESTAB",
  1995.     "FINWT1",
  1996.     "FINWT2",
  1997.     "CLOSEWT",
  1998.     "CLOSING",
  1999.     "LASTACK",
  2000.     "TIMEWT"
  2001.   };
  2002.   return(states[tcpcb->state]);
  2003. }
  2004. #endif
  2005.